<template>
  <div class="form-design" @drop.prevent.stop>
    <LeftPanel v-model="activeLeftMenu" />
    <!-- LEFT PANEL BEGIN -->
    <div class="left-panel">
      <!-- 组件拖拽区域 -->
      <ComponentDruggable v-if="activeLeftMenu === 'form'" />
      <!-- 数据模型 -->
      <datasource
        v-else
        :printInfo="printInfo"
        :datasetGroupList="datasetGroupList"
        :datasetList="datasetList"
        :datasetRelationList="datasetRelationList"
        :dictList="dictList"
      />
    </div>
    <!-- LEFT PANEL END -->
    <!-- DESIGN PANEL BEGIN -->
    <div class="design-panel">
      <el-row type="flex" align="middle" style="margin-left: -4px">
        <el-button-group key="align-control">
          <el-tooltip effect="dark" content="向左对齐">
            <el-button
              :size="buttonSize"
              class="align align-left"
              :icon="Histogram"
              @click="setElsAlign('left')"
            />
          </el-tooltip>
          <el-tooltip effect="dark" content="向右对齐">
            <el-button
              :size="buttonSize"
              class="align align-right"
              :icon="Histogram"
              @click="setElsAlign('right')"
            />
          </el-tooltip>
          <el-tooltip effect="dark" content="向上对齐">
            <el-button
              :size="buttonSize"
              class="align align-top"
              :icon="Histogram"
              @click="setElsAlign('top')"
            />
          </el-tooltip>
          <el-tooltip effect="dark" content="向下对齐">
            <el-button
              :size="buttonSize"
              class="align align-bottom"
              :icon="Histogram"
              @click="setElsAlign('bottom')"
            />
          </el-tooltip>
          <el-tooltip effect="dark" content="水平居中">
            <el-button
              :size="buttonSize"
              class="align align-center"
              :icon="Histogram"
              @click="setElsAlign('horizontal')"
            />
          </el-tooltip>
          <el-tooltip effect="dark" content="垂直居中">
            <el-button
              :size="buttonSize"
              class="align align-middle"
              :icon="Histogram"
              @click="setElsAlign('vertical')"
            />
          </el-tooltip>
          <el-tooltip effect="dark" content="横向分散">
            <el-button :size="buttonSize" :icon="Switch" @click="setElsAlign('distributeHor')" />
          </el-tooltip>
          <el-tooltip effect="dark" content="纵向分散">
            <el-button :size="buttonSize" :icon="Sort" @click="setElsAlign('distributeVer')" />
          </el-tooltip>
        </el-button-group>
        <el-button-group key="scale-control">
          <template v-for="(value, type) in paperTypes" :key="type">
            <el-button
              :size="buttonSize"
              :type="curPaperType === type ? 'primary' : 'default'"
              @click="setPaper(type, value)"
            >
              {{ type }}
            </el-button>
          </template>
          <el-popover
            v-model:visible="paperPopVisible"
            width="200"
            title="自定义纸张尺寸"
            trigger="click"
          >
            <template #default>
              <el-form
                ref="formRef"
                style="width: 150px"
                label-position="left"
                :model="customPaper"
              >
                <el-form-item
                  label="宽(mm)"
                  prop="width"
                  :rules="[
                    { required: true, message: '宽度必填' },
                    { type: 'number', message: '必须是数字' },
                  ]"
                >
                  <el-input v-model.number="customPaper.width" type="text" autocomplete="off" />
                </el-form-item>
                <el-form-item
                  label="高(mm)"
                  prop="width"
                  :rules="[
                    { required: true, message: '高度必填' },
                    { type: 'number', message: '必须是数字' },
                  ]"
                >
                  <el-input v-model.number="customPaper.height" type="text" autocomplete="off" />
                </el-form-item>
                <el-form-item style="justify-content: right">
                  <el-button type="primary" @click="handleCustomPaper">确定</el-button>
                </el-form-item>
              </el-form>
            </template>
            <template #reference>
              <el-button :size="buttonSize" :type="customPaperType == curPaperType ? 'primary' : ''"
                >自定义</el-button
              >
            </template>
          </el-popover>
          <el-button @click="hiprintTemplate.rotatePaper()" :size="buttonSize">旋转</el-button>
          <el-tooltip effect="dark" content="缩小视图">
            <el-button
              :size="buttonSize"
              :disabled="scaleValue <= scaleMin"
              :icon="ZoomOut"
              @click="changeScale(false)"
            />
          </el-tooltip>
          <el-button :size="buttonSize">
            {{ (scaleValue * 100).toFixed(0) + '%' }}
          </el-button>
          <el-tooltip effect="dark" content="放大视图">
            <el-button
              :size="buttonSize"
              :disabled="scaleValue >= scaleMax"
              :icon="ZoomIn"
              @click="changeScale(true)"
            />
          </el-tooltip>
        </el-button-group>
        <el-button-group>
          <el-tooltip effect="dark" content="撤销">
            <el-button
              :size="buttonSize"
              :icon="RefreshLeft"
              @click="undo"
              :disabled="historyManager.undoLength === 0"
            />
          </el-tooltip>
          <el-tooltip effect="dark" content="恢复">
            <el-button
              :size="buttonSize"
              :icon="RefreshRight"
              @click="redo"
              :disabled="historyManager.redoLength === 0"
            />
          </el-tooltip>
          <el-tooltip effect="dark" content="预览">
            <el-button :icon="View" :size="buttonSize" @click="preview" />
          </el-tooltip>
          <el-tooltip effect="dark" content="清空页面">
            <el-button :icon="Delete" :size="buttonSize" @click="clear" />
          </el-tooltip>
        </el-button-group>
        <el-button-group>
          <el-tooltip effect="dark" content="导入模板">
            <el-upload
              :auto-upload="false"
              :show-file-list="false"
              :limit="1"
              @change="importTemplate"
              style="float: left"
              accept=".json, application/json"
              ref="uploaderRef"
            >
              <template #trigger>
                <el-button
                  :icon="Upload"
                  :size="buttonSize"
                  style="
                    border-top-right-radius: 0;
                    border-bottom-right-radius: 0;
                    margin-right: -1px;
                  "
                />
              </template>
            </el-upload>
          </el-tooltip>
          <el-tooltip effect="dark" content="导出模板">
            <el-button :icon="Download" :size="buttonSize" @click="exportTemplate" />
          </el-tooltip>
        </el-button-group>
      </el-row>
      <div
        class="design-box"
        :key="currentFormId"
        style="margin-top: 10px; height: calc(100vh - 72px - 40px - 20px - 18px)"
      >
        <el-scrollbar class="paper-box" style="width: 100%; height: 100%">
          <div ref="designBox" style="max-width: 100%"></div>
        </el-scrollbar>
      </div>
    </div>
    <!-- DESIGN PANEL END -->
    <el-scrollbar class="attribute-panel">
      <div style="width: 100%; height: 100%; padding-bottom: 30px" ref="attributePanel">
        <!-- 属性面板 -->
      </div>
    </el-scrollbar>
  </div>
</template>

<script lang="ts" setup>
import {
  View,
  Histogram,
  ZoomOut,
  ZoomIn,
  RefreshLeft,
  RefreshRight,
  Switch,
  Sort,
  Delete,
  Download,
  Upload,
} from '@element-plus/icons-vue';
import { treeDataTranslate, traverseTree } from '@/common/utils';
import { ANY_OBJECT } from '@/types/generic';
import { ReportDatasetGroupController } from '@/api/report';
import { DictionaryController } from '@/api/system';
import { DatasetType, ReportRelationType } from '@/common/staticDict/report';
import { Dialog } from '@/components/Dialog';
import LeftPanel from './components/LeftPanel.vue';
import Datasource from './components/Datasource.vue';
import ComponentDruggable from './components/Component.vue';
import { hiprint } from './index';
import { ElMessage, ElMessageBox, UploadFile, UploadRawFile } from 'element-plus';
import HistoryManager from './history-manager';
import HiPrintPreview from './components/HiPrintPreview.vue';

const customPaperType = 'other';
const paperTypes = {
  A3: {
    width: 420,
    height: 296.6,
  },
  A4: {
    width: 210,
    height: 296.6,
  },
  A5: {
    width: 210,
    height: 147.6,
  },
  B3: {
    width: 500,
    height: 352.6,
  },
  B4: {
    width: 250,
    height: 352.6,
  },
  B5: {
    width: 250,
    height: 175.6,
  },
};

const props = defineProps<{ printInfo: ANY_OBJECT }>();

const datasetList = ref<ANY_OBJECT[]>([]);
const datasetGroupList = ref<ANY_OBJECT[]>([]);
const datasetRelationList = ref<ANY_OBJECT[]>([]);
const dictList = ref<ANY_OBJECT[]>([]);

const buttonSize = ref('small');
const currentFormId = ref('');
const designBox = ref();
const preView = ref();
const attributePanel = ref();
const uploaderRef = ref();

const curPaperType = ref('A4');
const curPaper = ref({
  width: 210,
  height: 296.6,
});
const customPaper = ref(curPaper.value);
const handleCustomPaper = () => {
  setPaper(customPaperType, customPaper.value);
  paperPopVisible.value = false;
};

const paperPopVisible = ref(false);

const activeLeftMenu = ref('form');

const getClientHeight = computed(() => {
  return props.height.value;
});

const historyManager = new HistoryManager(20);
let history = 0;
const addHistory = (type: string, json: ANY_OBJECT | null) => {
  history++;
  historyManager.addHistory(type, json);
};

let hiprintTemplate;
let initailJson = null;

const loadReportDictDropdownList = () => {
  dictList.value = [];
  DictionaryController.dictReportDict({})
    .then(res => {
      dictList.value = res.getList();
    })
    .catch(e => {
      // 错误信息
    });
};
const getPrintJson = () => {
  return hiprintTemplate ? hiprintTemplate.getJson() : undefined;
};
/**
 * 获取数据集以及关联数据
 */
const loadAllDatasetInfo = () => {
  console.log('loadAllDatasetInfo ==>');
  return new Promise((resolve, reject) => {
    ReportDatasetGroupController.listAll({})
      .then(res => {
        datasetGroupList.value = (res.data.reportDatasetGroupList || []).map(item => {
          return {
            ...item,
            id: item.groupId,
            name: item.groupName,
          };
        });
        datasetRelationList.value = (res.data.reportDatasetRelationList || []).map(item => {
          return {
            ...item,
            id: item.relationId,
            name: item.variableName,
            columnList: undefined,
          };
        });
        datasetList.value = (res.data.reportDatasetList || []).map(item => {
          try {
            let info = JSON.parse(item.datasetInfo);
            item.datasetParamList = info.paramList;
            if (item.datasetType === DatasetType.API) {
              const root = treeDataTranslate(info.columnList, 'columnId', 'parentId');
              item.columnList = (root[0] || {}).children;
            }
          } catch (e) {
            item.datasetParamList = [];
          }
          let dataset = {
            ...item,
            id: item.datasetId,
            name: item.datasetName,
            columnList: item.columnList,
          };

          dataset.relationList = datasetRelationList.value.filter(relation => {
            const ret = relation.masterDatasetId === item.datasetId;
            return ret;
          });

          return dataset;
        });
        res.data.columnList.forEach(item => {
          item.id = item.columnName;
          item.name = item.columnName;
        });
        const columnList = res.data.columnList || [];
        columnList.forEach(column => {
          const datasetId = column.datasetId;
          const dataset = datasetList.value.find(item => item.datasetId === datasetId);
          if (dataset != null) {
            if (dataset.columnList == null) dataset.columnList = [];
            dataset.columnList.push(column);
          }
        });
        console.log('loadAllDatasetInfo datasetList ==>', datasetList.value);
        resolve(datasetList.value);
      })
      .catch(e => {
        console.warn('loadAllDatasetInfo error', e);
        reject(e);
      });
  });
};

const datasetColumnList = computed(() => {
  if (props.printInfo && Array.isArray(props.printInfo.fragmentJson)) {
    return props.printInfo.fragmentJson.map(item => {
      return {
        ...item,
        dataset: datasetList.value.find(dataset => dataset.id === item.datasetId) || {},
      };
    });
  }

  return undefined;
});

onMounted(() => {
  loadReportDictDropdownList();
  loadAllDatasetInfo()
    .then(res => {
      hiprintTemplate = new hiprint.PrintTemplate({
        settingContainer: attributePanel.value,
        onImageChooseClick: target => {
          // 这里可以实现自己的选择图片的功能，并设置图片地址
          console.log('=== image choose click ===', target);
          // 图片选择回调  TODO
          target.setValue('https://element-plus.org/images/element-plus-logo.svg');
        },
        history: true, // 启用历史记录功能
        onDataChanged: (type, paper) => {
          // console.log("data change", type, paper);
          // 将操作类型和状态一起记录到历史
          addHistory(type, paper);
        },
        getFields: isTable => {
          let tempList: ANY_OBJECT[] = [];
          let path: string[] = [];
          (datasetColumnList.value || []).forEach((item: ANY_OBJECT) => {
            path = [];
            path.push(item.variableName);
            let dataset = item.dataset;
            if (dataset.datasetType !== DatasetType.API) {
              // 字段列表
              if (Array.isArray(dataset.columnList) && !isTable && !item.loop) {
                // 非循环的数据集，并且绑定非表格
                dataset.columnList.forEach(column => {
                  tempList.push({
                    field: path.join('.') + '.' + column.columnName,
                    text:
                      path.join('.') + '.' + column.columnName + '(' + column.columnComment + ')',
                  });
                });
              }
              if (item.loop && isTable) {
                // 循环数据集，绑定表格
                tempList.push({
                  field: path.join('.'),
                  text: path.join('.') + '(' + item.showName + ')',
                });
              }
              // 关联列表
              if (Array.isArray(dataset.relationList) && !item.loop) {
                // 非循环数据集的关联
                dataset.relationList.forEach(relation => {
                  const relationSlaveDataset = datasetList.value.find(
                    item => item.id === relation.slaveDatasetId,
                  );
                  if (isTable && relation.relationType === ReportRelationType.ONE_TO_MANY) {
                    // 表格绑定的字段只能是一对多关联数据
                    tempList.push({
                      field: path.join('.') + '.' + relation.variableName,
                      text: path.join('.') + '.' + relation.variableName,
                    });
                  }
                  if (!isTable && relation.relationType === ReportRelationType.ONE_TO_ONE) {
                    // 非表格绑定的字段只能是一对一关联数据
                    path.push(relation.variableName);
                    if (relationSlaveDataset && Array.isArray(relationSlaveDataset.columnList)) {
                      relationSlaveDataset.columnList.forEach(column => {
                        tempList.push({
                          field: path.join('.') + '.' + column.columnName,
                          text:
                            path.join('.') +
                            '.' +
                            column.columnName +
                            '(' +
                            column.columnComment +
                            ')',
                        });
                      });
                    }
                  }
                });
              }
            } else {
              // API数据集
              if (item.loop && isTable) {
                // 循环数据集，绑定表格
                tempList.push({
                  field: path.join('.'),
                  text: path.join('.') + '(' + item.showName + ')',
                });
              } else {
                if (Array.isArray(dataset.columnList) && !item.loop) {
                  // 非循环的数据集
                  console.log(dataset.columnList);
                  traverseTree(dataset.columnList, (node, treePath) => {
                    console.log('=== node ===', node, treePath);
                    const treePathName = treePath
                      ? treePath.map(item => item.columnName).join('.')
                      : node.columnName;
                    if (isTable && node.fieldType === 'Array') {
                      // 表格绑定数组数据
                      tempList.push({
                        field: path.join('.') + '.' + treePathName,
                        text: path.join('.') + '.' + treePathName + '(' + node.columnComment + ')',
                      });
                    }
                    if (!isTable && node.fieldType !== 'Array') {
                      // 非表格绑定非数组数据
                      tempList.push({
                        field: path.join('.') + '.' + treePathName,
                        text: path.join('.') + '.' + treePathName + '(' + node.columnComment + ')',
                      });
                    }
                    return node.fieldType === 'Array';
                  });
                }
              }
            }
          });
          return tempList;
        },
      });
      // 初始化打印设计
      hiprintTemplate.design(designBox.value);

      // 模拟点击打印区域以显示纸张属性
      setTimeout(() => {
        const paperPanel: HTMLElement | null = document.querySelector('.hiprint-printPaper');
        if (paperPanel) {
          paperPanel.click();
          if (props.printInfo?.hiprintDataJson) {
            hiprintTemplate.update(JSON.parse(props.printInfo.hiprintDataJson));
          } else {
            initailJson = hiprintTemplate.getJson();
          }
          addHistory('初始化', initailJson);
          console.log('=== initailJson ===', initailJson);
        }
      }, 100);
    })
    .catch(e => {
      console.error('加载数据集失败', e);
    });
});

const setElsAlign = (align: string) => {
  try {
    hiprintTemplate.setElsAlign(align);
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
  } catch (e: Error | any) {
    ElMessage.error(`操作失败: ${e?.message || e || '未知错误'}`);
  }
};

const setPaper = (type: string, value: ANY_OBJECT) => {
  curPaperType.value = type;
  try {
    if (Object.keys(paperTypes).includes(type)) {
      curPaper.value = {
        width: value.width,
        height: value.height,
      };
      hiprintTemplate.setPaper(value.width, value.height);
    } else {
      curPaper.value = {
        width: value.width,
        height: value.height,
      };
      hiprintTemplate.setPaper(value.width, value.height);
    }
    customPaper.value = curPaper.value;
  } catch (error) {
    ElMessage.error(`操作失败: ${error}`);
  }
};

const updateTemplate = (templateJson = null) => {
  try {
    hiprintTemplate.update(templateJson);
  } catch (e) {
    ElMessage.error(`更新失败: ${e}`);
  }
};

const undo = () => {
  history--;
  // 获取上一个状态
  const lastJson = historyManager.undo();
  console.log('undo', historyManager.undoLength);
  console.log('redo', historyManager.redoLength);
  console.log('lastJson', lastJson);
  if (history === 0) {
    // 恢复到初始状态
    updateTemplate(initailJson);
  } else {
    // 恢复到上一个状态
    updateTemplate(lastJson);
  }
};
const redo = () => {
  console.log('redo', historyManager.redoLength);
  console.log('undo', historyManager.undoLength);
  if (historyManager.redoLength > 0) {
    // 获取下一个状态
    const nextJson = historyManager.redo();
    //恢复到下一个状态
    updateTemplate(nextJson || initailJson);
  }
};

const scaleValue = ref(1);
const scaleMax = 5;
const scaleMin = 0.5;

const changeScale = val => {
  let sv = scaleValue.value;
  if (val) {
    sv += 0.1;
    if (sv > scaleMax) sv = 5;
  } else {
    sv -= 0.1;
    if (sv < scaleMin) sv = 0.5;
  }
  console.log('scale', sv);
  if (hiprintTemplate) {
    hiprintTemplate.zoom(sv, true);
    scaleValue.value = sv;
  }
};

const restoreScale = () => {
  if (hiprintTemplate) {
    hiprintTemplate.zoom(1, true);
    scaleValue.value = 1;
  }
};

const clear = () => {
  ElMessageBox.confirm('确定要清空页面吗？', '', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      hiprintTemplate.clear();
    })
    .catch(() => {
      console.log('取消清空页面');
    });
};

const preview = () => {
  Dialog.show(
    'HiPrint预览',
    HiPrintPreview,
    {
      area: ['100vw', '100vh'],
      skin: 'fullscreen-dialog',
    },
    {
      printId: props.printInfo.printId,
      printParam: [],
      printName: props.printInfo.printName,
      path: 'thirdPrintPreview',
    },
    {
      fullscreen: true,
      pathName: '/thirdParty/thirdPrintSpreadSheet',
    },
  ).catch(e => {
    console.warn(e);
  });
};

const exportTemplate = () => {
  ElMessageBox.confirm('确定要导出打印模板吗？', '', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      const text = JSON.stringify(hiprintTemplate.getJson(), null, 2);
      const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
      const url = URL.createObjectURL(blob);

      const a = document.createElement('a');
      a.href = url;
      a.download = 'printTemplate.json';
      a.style.display = 'none';

      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    })
    .catch(() => {
      console.log('取消导出');
    });
};

const beforeUpload = (file: UploadRawFile) => {
  console.log('beforeUpload', file);
  const isJSON = file.type === 'application/json' || file.name.endsWith('.json'); // 双重校验
  if (!isJSON) {
    ElMessage.error('文件类型错误');
    return false;
  }
  const isLt10M = file.size / 1024 / 1024 < 10;
  if (!isLt10M) {
    ElMessage.error('文件大小不能超过 10MB');
    return false;
  }
  return true;
};

const importTemplate = (file: UploadFile) => {
  if (!file.raw) {
    ElMessage.error('文件为空');
    uploaderRef.value?.clearFiles();
    return;
  }
  if (!beforeUpload(file.raw)) {
    uploaderRef.value?.clearFiles();
    return;
  }

  const reader = new FileReader();
  reader.onload = function (e: ProgressEvent<FileReader>) {
    const content = e.target?.result;
    console.log('文件内容:', content);
    if (!content || typeof content !== 'string') {
      ElMessage.error('模板非法');
      return;
    }
    try {
      const json = JSON.parse(content);
      hiprintTemplate.update(json);
      let paperType = json.panels[0].paperType;
      let width = json.panels[0].width;
      let height = json.panels[0].height;
      curPaperType.value = paperTypes[paperType] ? paperType : customPaperType;
      curPaper.value = {
        width: width,
        height: height,
      };
      addHistory('update', json);
      ElMessage.success('导入成功');
    } catch (e) {
      ElMessage.error(`更新失败: ${e}`);
    }
  };
  reader.onerror = function (error) {
    console.error('读取文件失败:', error);
  };
  reader.readAsText(file.raw); // 以文本形式读取文件
  uploaderRef.value?.clearFiles();
};

const print = () => {
  // 浏览器预览打印
  hiprintTemplate.print(
    {},
    {
      styleHandler: () => {
        // 这里拼接成放html->head标签内的css/style
        // 1.例如：使用hiprin官网的样式
        let css =
          '<link href="http://hiprint.io/Content/hiprint/css/print-lock.css" media="print" rel="stylesheet">';
        // 2.重写样式：所有文本红色
        css += '<style>.hiprint-printElement-text{color:red !important;}</style>';
        return css;
      },
    },
    {
      callback: () => {
        console.log('浏览器打印窗口已打开');
      },
    },
  );
};

const saveForm = () => {
  console.log(hiprintTemplate.getJson());
};

defineExpose({
  saveForm,
  getPrintJson,
});
</script>

<style lang="scss" scoped>
.el-button + .el-button {
  margin-left: 0px;
}
.el-icon {
  color: rgb(96, 98, 102) !important;
}
.paper-box :deep(.el-scrollbar__view) {
  padding-left: 15px;
}
:deep(.hiprint-printPaper) {
  background-color: white;
}
:deep(.el-button-group) {
  margin: 4px;
}

.form-design {
  display: flex;
  height: 100%;
}
.form-design .attribute-panel :deep(.el-form-item) {
  margin-bottom: 12px;
}
.form-design .left-panel {
  display: flex;
  flex-direction: column;
  width: 288px;
  height: 100%;
  :deep(.form-card) {
    flex-grow: 0;
    flex-shrink: 0;
    height: 280px;
  }

  :deep(.base-card-header) {
    height: 56px;
    line-height: 56px;

    i {
      font-size: 14px;
      color: #999;

      span {
        font-size: 14px;
        color: #333;
        font-weight: bold;
      }
    }
  }
}
.form-item {
  height: 44px;
  .form-item-title {
    span {
      overflow: hidden;
      max-width: 100px;
      font-size: 14px;
      text-overflow: ellipsis;
      white-space: nowrap;
      color: #333;
      font-weight: 400;
      cursor: pointer;
    }
    .tag {
      padding: 3px 8px;
      margin-left: 8px;
      font-size: 14px;
      color: #999;
      background: #f6f7f9;
      border-radius: 4px;
    }
  }
  .font-item-menu {
    font-size: 18px;
    color: #999;
  }
}
.form-item.active {
  .form-item-title {
    span {
      color: $color-primary;
    }
    .tag {
      color: #ffb800;
      background: #fff8e5;
    }
  }
}
.widget-group {
  .group-title {
    height: 44px !important;
    color: #333 !important;
    font-weight: bold !important;
    line-height: 44px !important;
  }
  .group-widget-list {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;

    .group-widget-item {
      margin-bottom: 10px;
      .icon {
        width: 64px;
        height: 64px;
        font-size: 26px;
        text-align: center;
        color: #666;
        border: 1px solid #e8e8e8;
        border-radius: 4px;
        cursor: pointer;
        line-height: 64px;
      }

      .icon:hover {
        background: #f6f7f9;
      }

      .name {
        overflow: hidden;
        width: 64px;
        height: 26px;
        font-size: 12px;
        text-align: center;
        text-overflow: ellipsis;
        white-space: nowrap;
        color: #666;
        line-height: 26px;
        font-weight: 400;
      }
    }
  }
}
.design-panel {
  flex-grow: 1;
  width: 200px;
  padding: 10px 18px 18px;
  .design-box {
    display: flex;
    justify-content: center;
    width: 100%;
    height: calc(100% - 48px);
  }
}
.attribute-panel {
  flex-shrink: 0;
  width: 328px;
  background: white;
  flex-grow: 0;
}
.device-item {
  display: inline-block;
  width: 32px;
  height: 32px;
  font-size: 24px;
  text-align: center;
  color: #666;
  line-height: 32px;
  cursor: pointer;
}
.device-item.active {
  color: $color-primary;
  background: #fff1e5;
  cursor: pointer;
}
.device-item.disabled {
  cursor: not-allowed !important;
}

.base-card :deep(.el-card__body) {
  height: 100%;
}
// Jie. 20250716 修改高度
.attribute-panel :deep(.el-tabs__nav) {
  padding-top: 10px;
  height: 57px;
}
.attribute-panel :deep(.el-tabs__item) {
  font-size: 14px;
}
.attribute-panel :deep(.el-tabs__nav-wrap) {
  background: #fcfcfc;
}
.attribute-panel :deep(.el-tabs__header) {
  margin: 0;
}
.attribute-panel :deep(.el-tabs__nav) {
  margin-left: 16px;
}
.attribute-panel :deep(.el-form-item__label) {
  padding-right: 0;
  font-size: 14px;
  color: #666;
}
.attribute-panel :deep(.el-tabs__nav-wrap::after) {
  height: 1px;
}
.attribute-panel :deep(.el-radio__label) {
  padding-left: 8px;
}
.attribute-panel :deep(.el-radio) {
  margin-right: 24px;
}
.attribute-panel :deep(.el-radio:last-child) {
  margin-right: 0;
}
.el-button--small {
  height: 32px !important;
}
</style>

<style lang="scss">
.el-tooltip__popper {
  .el-button {
    width: 100%;
    text-align: left;
    padding-left: 8px;
    padding-right: 8px;
  }
  .el-button:hover {
    background: rgba(64, 158, 255, 0.8);
    color: #ffffff;
  }
}
.align {
  position: relative;
  i {
    &:after {
      content: '|';
      position: absolute;
      left: 15px;
      transform: rotate(90deg) translate(200%, 60%);
    }
  }
}
.align.align-left i {
  transform: rotate(90deg);
}
.align.align-right i {
  transform: rotate(-90deg);
}
.align.align-top i {
  transform: rotate(180deg);
}
.align.align-bottom i {
  transform: rotate(0deg);
}
.align.align-center i {
  transform: rotate(90deg);
  &:after {
    transform: rotate(90deg) translate(0, 60%);
  }
}
.align.align-middle i {
  transform: rotate(0deg);
  &:after {
    transform: rotate(90deg) translate(0, 60%);
  }
}

// 页面样式
.hiprint-printTemplate {
  margin-top: 15px;
}
.hiprint_rul_wrapper {
  margin-top: -15px;
  top: 0px;
}
// 属性面板样式
.hiprint-option-items .hiprint-option-item {
  width: 100% !important;
}
.prop-tabs .prop-tab-items li.active,
.prop-tabs .prop-tab-items {
  height: 50px;
  line-height: 50px;
}
.prop-tabs .prop-tab-items {
  margin-bottom: 15px;
}
.prop-tabs .prop-tab-items .prop-tab-item .tab-title {
  font-weight: normal;
}
.prop-tabs .prop-tab-items li.active {
  color: var(--el-color-primary);
  border-bottom: 2px solid #f70;
}
.prop-tabs .prop-tab-items li.active .tab-title {
  font-weight: bold !important;
}
.hiprint-option-items {
  padding: 20px 18px;
}
.prop-tabs .prop-tab-items .prop-tab-item .tab-title {
  padding: 0 18px;
}
.prop-tabs .hiprint-option-items {
  padding: 0 18px;
}
.hiprint-option-item-submitBtn {
  margin-left: 24px;
  background: #f70;
}
.hiprint-option-items .hiprint-option-item-submitBtn {
  margin-left: 2px !important;
}
.hiprint-option-item-settingBtn {
  display: none;
}
input[placeholder='请输入图片地址'] {
  width: 100% !important;
}
.hiprint-option-item-label {
  display: inline-block;
  vertical-align: middle;
  height: 22px;
  text-align: left;
  margin-bottom: 8px;
  line-height: 22px;
  font-size: 14px;
  color: #333;
  width: 100%;
  padding: 0 12px 0 0;
}

.hiprint-option-item-field:has(> textarea) {
  height: auto !important;
  padding: 0 !important;
}
.hiprint-option-item-field:has(> div:first-child) {
  margin-bottom: 13px;
  height: 32px;
  input:not([type='checkbox']),
  select {
    flex-grow: 1;
    color: #606266 !important;
    font-size: inherit;
    height: 32px !important;
    line-height: 32px !important;
    box-sizing: border-box;
    border-radius: 4px;
    transition: box-shadow 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
    transform: translate3d(0, 0, 0);
    box-shadow: 0 0 0 1px #dcdfe6 inset;
    height: 32px !important;
  }
  input:focus {
    outline: none !important;
  }
  input::placeholder,
  textarea::placeholder {
    color: #a8abb2;
  }
  input:not([type='checkbox']):hover {
    box-shadow: 0 0 0 1px #c0c4cc inset;
  }
  input:not([type='checkbox']):focus,
  textarea:focus,
  select:focus {
    box-shadow: 0 0 0 1px #f70 inset;
  }
}
.hiprint-option-item-field:not(:has(> div)) {
  height: 32px;
  width: 100%;
  display: inline-flex;
  flex-grow: 1;
  align-items: center !important;
  justify-content: center !important;
  padding: 1px 11px;
  background-color: #ffffff;
  background-image: none;
  border-radius: 4px;
  cursor: text;
  transition: box-shadow 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
  transform: translate3d(0, 0, 0);
  box-shadow: 0 0 0 1px #dcdfe6 inset;
  padding: 1px 11px;
  margin: 0;
  input,
  textarea,
  select {
    width: 100%;
    padding: auto;
  }
  input,
  select {
    flex-grow: 1;
    color: #606266 !important;
    font-size: inherit;
    height: calc(32px - 2px);
    line-height: calc(32px - 2px);
    padding: 0 !important;
    outline: none !important;
    border: none !important;
    background: none !important;
    box-sizing: border-box;
  }
  input:focus {
    outline: none !important;
  }
  input::placeholder,
  textarea::placeholder {
    color: #a8abb2;
  }
  .hiprint-option-items .minicolors {
    position: relative;
    width: 100%;
    padding-left: 23px;
  }
  .hiprint-option-items .minicolors-theme-bootstrap .minicolors-swatch {
    top: 0 !important;
  }
}
.hiprint-option-item-field:not(:has(> div)):hover {
  box-shadow: 0 0 0 1px #c0c4cc inset;
}
.hiprint-option-item-field:not(:has(> div)):has(input:focus, textarea:focus, select:focus) {
  box-shadow: 0 0 0 1px #f70 inset;
}
.minicolors-input {
  width: 100% !important;
}
.hiprint-option-item-field:not(:has(> :first-child.minicolors)) {
  .minicolors {
    width: 75%;
  }
}
.hiprint-option-items .minicolors-theme-bootstrap .minicolors-swatch {
  top: 8px;
}
.prop-tabs .prop-tab-items {
  height: 49px;
  line-height: 49px;
  border-bottom: 1px solid #ddd !important;
}
.prop-tabs .prop-tab-items .prop-tab-item .tab-title {
  width: 30px;
  line-height: 50px;
  height: 50px;
  display: block;
  padding: 0;
}
.prop-tabs .prop-tab-items .prop-tab-item {
  padding: 0 18px;
  border-bottom: none !important;
  height: 50px;
  line-height: 50px;
}
.prop-tabs .prop-tab-items li.active {
  border-bottom: none !important;
}
.prop-tabs .prop-tab-items li.active .tab-title {
  border-bottom: 2px solid #f70;
}
/* 隐藏基础模块下部分属性 */
.hiprint-option-items:not([data-title]) > :nth-child(3),
.hiprint-option-items:not([data-title]) > :nth-child(4),
.hiprint-option-items:not([data-title]) > :nth-child(5),
.hiprint-option-items:not([data-title]) > :nth-child(6),
.hiprint-option-items:not([data-title]) > :nth-child(9) {
  display: none;
}
[data-title='高级']:has(> :nth-child(13)) {
  > :nth-child(1),
  > :nth-child(2),
  > :nth-child(3),
  > :nth-child(4),
  > :nth-child(5),
  > :nth-child(6) {
    display: none;
  }
}
</style>
